home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
System Booster
/
System Booster.iso
/
Systemmonitors
/
Snoopy
/
Sources
/
patch.asm
< prev
next >
Wrap
Assembly Source File
|
1996-09-26
|
7KB
|
238 lines
incpath include:
maclib sm.mac
macfile macro.i
macfile snoopy.i
macfile extern/main
macfile macros/patch
section main,code
***********************************************************************************
;-------------- this is the patch-function that replaces any original LIBRARY code.
;-------------- Note that we have a little recursion-protector here that will
;-------------- prevents recursions that occur inside the original vector
;-------------- just aslong as the PatchCode() is active
;--------------
;-------------- NOTE: the device patch follows below & is a LOT more complicated
xdef Patch_START
Patch_START dc.b PATCH_IDSTRING ; sphead_Ident
dc.l 0 ; sphead_Owner
dc.l 0 ; sphead_OriginalFunction
xdef PatchInfoStruct
PatchInfoStruct dc.l 0 ; sphead_Info
push a0
lea (recursionWord,pc),a0
tst.w (a0)
bne.b OriginalCode
move.w #-1,(a0)
pop a0
addq.l #1,(ActiveCalls)
push a6
bsr.b SetupReplyMsg1
push a6
movea.l (4,sp),a6
xdef OriginalVector0
OriginalVector0 jsr $ffff0000
pop a6
bsr SendReplyMsg1
lea (recursionWord,pc),a6
clr.w (a6)
pop a6
subq.l #1,(ActiveCalls)
rts
OriginalCode pop a0 ; from initial push at line #ß
xdef OriginalVector1
OriginalVector1 jsr $ffff000
rts
;-------------- HEY DUDES: I know this is a bit messy, but I couldn't think of
;-------------- anything better for my purpose. Of course, Snoopy will probably
;-------------- miss out one or two calls in "stress situations", but
;-------------- "better safe than sorry".....
recursionWord dc.w 0 ; if bit15 is 0, then no call is currently active
***********************************************************************************
;-------------- sets up the replymsg given by the patch function
;--------------
;-------------- => d0-d7/a0-a5: Registers before function call
;-------------- <= a6: PatchCallMessage structure
;-------------- allocate data structure
SetupReplyMsg1 pushm d0-d7/a0-a5
movea.l (execBase).w,a6
move.l (thistask),d0
cmp.l (ThisTask,a6),d0
beq .SKIPTHIS
move.l #smsg_SIZEOF,d0
move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
CALL AllocMem,<(execBase).w>
move.l d0,a6
popm d0-d7/a0-a5
;-------------- fail if NULL; else save all registers
cmpa.l #0,a6
beq .FAIL
SAVEREGS smsg_RegsBeforeCall
.FAIL rts
.SKIPTHIS suba.l a6,a6
popm d0-d7/a0-a5
rts
***********************************************************************************
;-------------- sends the reply message back
;--------------
;-------------- => d0-d7/a0-a5: Registers after function call
;--------------
;-------------- fail if NULL; else save all registers
SendReplyMsg1 cmpa.l #0,a6
beq .FAIL
SAVEREGS smsg_RegsAfterCall
pushm d0-d7/a0-a5
movea.l (execBase).w,a0
move.l (ThisTask,a0),(smsg_Task,a6)
move.l (PatchInfoStruct,pc),(smsg_Info,a6)
movea.l a6,a5 ; a5 = Data structure
movea.l a0,a6
;-------------- setup other message stuff
move.b #NT_MESSAGE,(LN_TYPE,a5)
move.w #smsg_SIZEOF,(MN_LENGTH,a5)
move.w #MSGTYPEF_LIBRARY,(smsg_Type,a5) ; **DO NOT REMOVE**
move.l #0,(MN_REPLYPORT,a5)
move.l (myport),a0 ; port
move.l a5,a1 ; message
CALL PutMsg
;-------------- new: handle timeout
push a6
movea.l (PatchInfoStruct,pc),a1
move.l (spatch_Timeout,a1),d1
beq.b .NOTIMEOUT
cmpi.l #-1,d1
beq.b .BREAKOUT
BRBS.B #31,d1,.NOTIMEOUT ; skip negative timeout values
CALL Delay,<(dosBase)>
bra.b .NOTIMEOUT
.BREAKOUT move.l #SIGBREAKF_CTRL_C,d0
CALL Wait,<(execBase).w>
.NOTIMEOUT pop a6
popm d0-d7/a0-a5
.FAIL rts
xdef Patch_SIZEOF
Patch_SIZEOF dc.l *-Patch_START
;-------------- Now the two patches for BeginIO()/AbortIO(); Both patches
;-------------- are very small and "minimalistic" (I had a much more complicated
;-------------- one in the beginning but it didn't work -> this one does ;-)
xdef BeginIO_Patch
BeginIO_Patch: dc.b PATCH_IDSTRING ; sphead_Ident
dc.l 0 ; sphead_Owner
dc.l 0 ; sphead_OriginalFunction
dc.l 0 ; sphead_Info (size of memory)
dc.l 0 ; sphead_DevicePtr
;-------------- "here we go again with a funky intro": BeginIO gets the
;-------------- IOBlock in a1 and a pointer to the device in a6.
addq.l #1,(ActiveCalls)
push d4
move.l (4,sp),d4
pushm d0-d3/d5-d7/a0-a6
lea (BeginIO_Patch,pc),a5
move.w #MSGTYPEF_DEVICE|MSGTYPEF_BEGINIO,d5
jsr PerformDevicePatch
popm d0-d3/d5-d7/a0-a6
pop d4
subq.l #1,(ActiveCalls)
xdef BeginIO_Jump
BeginIO_Jump: jsr $ffff0000 ; proceed with IO call
rts
xdef BeginIO_SIZEOF
BeginIO_SIZEOF dc.l *-BeginIO_Patch
xdef AbortIO_Patch
AbortIO_Patch: dc.b PATCH_IDSTRING ; sphead_Ident
dc.l 0 ; sphead_Owner
dc.l 0 ; sphead_OriginalFunction
dc.l 0 ; sphead_Info (size of memory)
dc.l 0 ; sphead_DevicePtr
addq.l #1,(ActiveCalls)
push d4
move.l (4,sp),d4
pushm d0-d3/d5-d7/a0-a6
lea (AbortIO_Patch,pc),a5
move.w #MSGTYPEF_DEVICE,d5
jsr PerformDevicePatch
popm d0-d3/d5-d7/a0-a6
pop d4
subq.l #1,(ActiveCalls)
xdef AbortIO_Jump
AbortIO_Jump: jsr $ffff0000 ; proceed with IO call
rts
xdef AbortIO_SIZEOF
AbortIO_SIZEOF dc.l *-AbortIO_Patch
**************************************************************************
;-------------- Really perform a device patch (because BeginIO()/AbortIO()
;-------------- really are *VERY* similar)
;--------------
;-------------- => a5: APTR begin_of_patch
;-------------- d5: WORD flags
;--------------
;-------------- Note: This function DOES NOT save any registers, the patches
;-------------- above have to take care of this!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;--------------
ENTRY PerformDevicePatch
move.l a1,d6 ; d6 = pointer to IO block
move.l #sdmsg_SIZEOF,d7
add.l (sphead_Info,a5),d7 ; d0 = size of allocated memory
move.l d7,d0
move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
CALL AllocMem,<(execBase).w>
tst.l d0
beq.b PerformDevicePatch_done
movea.l d0,a4
move.l d4,(sdmsg_PC,a4)
;-------------- copy IO block
move.l (sphead_Info,a5),d0
subq.w #1,d0
lea (sdmsg_SIZEOF,a4),a1 ; target
movea.l d6,a0 ; source
.COPYMEMORY move.b (a0)+,(a1)+
dbra d0,.COPYMEMORY
;-------------- setup other message stuff
move.b #NT_MESSAGE,(LN_TYPE,a4)
move.w d7,(MN_LENGTH,a4)
move.l (sphead_DevicePtr,a5),(sdmsg_DeviceBase,a4)
move.l (ThisTask,a6),(sdmsg_Task,a4)
move.w d5,(sdmsg_Type,a4) ; **DO NOT REMOVE**
move.l #0,(MN_REPLYPORT,a4)
;-------------- send message and immediately continue processing
move.l (myport),a0 ; port
move.l a4,a1 ; message
CALL PutMsg
DONE PerformDevicePatch
section memory,bss
;-------------- *** DO NOT REMOVE THIS ***, its here just to make sure
;-------------- SLINK doesn't place the BSS section as the second section
;-------------- (DETACHSTARTUPARGS macro (see main.asm) relys on a certain
;-------------- section layout which could be scratched somehow)
ds.w 1
**************************************************************************
;--------------